package com.xstudio.pvzreborn.event;

import com.xstudio.pvzreborn.capability.CapManager;
import com.xstudio.pvzreborn.capability.IEditable;
import com.xstudio.pvzreborn.item.ItemManager;
import com.xstudio.pvzreborn.item.ItemNames;
import com.xstudio.pvzreborn.network.ManagerNetwork;
import com.xstudio.pvzreborn.network.PlayerCapabilityPacket;
import com.xstudio.pvzreborn.sound.SoulMusic;
import com.xstudio.pvzreborn.utils.LevelUtils;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.boss.wither.WitherBoss;
import net.minecraft.world.entity.monster.Creeper;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.living.LivingDropsEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.world.ExplosionEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;

@EventBusSubscriber
public final class EventListener {

	@SubscribeEvent
	public static void onExplosion(ExplosionEvent.Detonate event) {
		Explosion explosion = event.getExplosion();
		Vec3 pos = explosion.getPosition();
		Level level = event.getWorld();

		if (!level.isClientSide) {
			if (explosion.getSourceMob() instanceof Creeper creeper && creeper.isIgnited()) {
                LevelUtils.spawnItemEntity(level, pos, ItemManager.getDefaultItemStack(ItemNames.CREEPER_GLAND));
			}

			if (level.getBlockState(new BlockPos(pos).below()).is(Blocks.BEDROCK)) {
                LevelUtils.spawnItemEntity(level, pos, new ItemStack(ItemManager.getItem(ItemNames.BEDROCK_DUST), 2));
			}
		}
	}

	@SubscribeEvent
	public static void onLivingDrops(LivingDropsEvent event) {
		LivingEntity entity = event.getEntityLiving();
		Level level = entity.level;
		if (!level.isClientSide && level.dimension().equals(Level.NETHER) && entity instanceof WitherBoss) {
            event.getDrops().removeIf(itemEntity -> itemEntity.getItem().is(Items.NETHER_STAR));
            event.getDrops().add(LevelUtils.newItemEntity(level, entity.getOnPos(), ItemManager.getItem(ItemNames.UNCONTROLLABLE_NETHER_STAR)));
		}
	}

	@SubscribeEvent
	public static void onPlayerCloned(PlayerEvent.Clone event) {
		ServerPlayer player = (ServerPlayer) event.getPlayer();
		ServerPlayer original = (ServerPlayer) event.getOriginal();
		// 同步 Cap 数据
		original.reviveCaps();
		copyValue(original, player, CapManager.SUNSHINE);
		copyValue(original, player, CapManager.DAVE_COIN);
		copyValue(original, player, CapManager.PLANT_FOOD);
	}

	@SubscribeEvent
	public static void onEntityJoinWorld(EntityJoinWorldEvent event) {
		Level level = event.getWorld();
		Entity entity = event.getEntity();
		if (entity instanceof WitherBoss wither && level.dimension().equals(Level.NETHER)) {
			if (!level.isClientSide) {
				entity.setCustomNameVisible(false);
				entity.setCustomName(new TranslatableComponent("entity.pvzreborn.nether_wither"));
			} else {
				SoulMusic.play(wither);
			}
		}

        // 客户端通知服务端同步 Cap 数据
		if (level.isClientSide && entity instanceof Player) {
			ManagerNetwork.sendToServer(new PlayerCapabilityPacket.NotificationServer());
		}
	}

	private static <T extends IEditable<?>> void copyValue(ServerPlayer original, ServerPlayer player, Capability<T> capability) {
		original.getCapability(capability).ifPresent(old -> player.getCapability(capability).ifPresent(now -> now.setValue(old.getValue(), player)));
	}

}
